package com.shang.core;

import com.shang.core.base.AbstractBitMap;
import com.shang.core.base.CodecException;
import com.shang.core.base.Meta;
import com.shang.core.base.PadPosition;
import com.shang.core.base.Value;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 已配置128个空子域（尽管65域不存在，但为了减少特殊处理，65域添加为空子域），减少后续初始化代码
 * <p>
 * 限定子域名称以F开头，请选择性使用（1域为扩展位图，名称为BITMAP2）
 * <p>
 * Created by shangwei2009@hotmail.com on 2021/9/26 17:04
 */
public class BitMap extends AbstractBitMap {

    /**
     * 002~009、010~099、100~119、120~128
     */
    private static final Pattern FIELD_NAME = Pattern.compile("^F(00[2-9]|0[1-9]\\d|1[0-1]\\d|12[0-8])$");

    public BitMap(Meta meta) {
        super(meta, StandardCharsets.US_ASCII, PadPosition.NONE, "");
        // 给位图配置128个空域，减少后续初始化代码
        child(new BlankValue("BITMAP2"));
        for (int i = 2; i <= 128; i++) {
            child(new BlankValue(String.format("F%03d", i)));
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends Value> T child(Value child) {
        final Value value = super.child(child);
        if (!"BITMAP2".equals(child.getFieldName()) && !FIELD_NAME.matcher(child.getFieldName()).matches()) {
            throw new CodecException(getFieldName() + "的子域名称只能在BITMAP2、F002~F128之间");
        }
        return (T) value;
    }

    @Override
    protected String valueStr(String valueStr) {
        final byte[] bytes = DatatypeConverter.parseHexBinary(valueStr);
        return Arrays.stream(ArrayUtils.toObject(bytes))
                .map(aByte -> StringUtils.leftPad(Integer.toBinaryString(aByte & 0xFF), 8, '0'))
                .collect(Collectors.joining());
    }
}
